package designPattern.creation.singletonpattern;

/**
 * @author 张琪
 * @date 2023/1/29 17:00
 */
public class SafeSingleton {

    private String name = "懒汉式单例-线程安全2 -- 双重检查锁定";
    private SafeSingleton() {}

    /**
     * 在 java 中 new SafeSingleton() 不是一个原子性操作, 存在指令重排序; 在高并发的情况下, 可能会读到<br/>
     * 一个不为空但没有完成初始化的对象, 从而造成错误<br/>
     * 使用 {@code volatile} 禁止指令重排序, 使得new操作成为原子性操作, 保证线程安全
     */
    private volatile static SafeSingleton singleton=null;

    /**
     * 两次判断 + volatile; 保证线程安全, 且避免了每次同步的性能损耗
     * @return
     */
    public static SafeSingleton getInstance() {
        // 高并发下, A,B两个线程都会通过第一个 if
        if (singleton == null) {
            // 若 A 先抢到锁, 实例化完成后; B 获取锁,如果不做第二个 if 判断, 则会第二次实例化;
            // 因此需要在锁中加一层判断
            synchronized (SafeSingleton.class) {
                if (singleton == null) {
                    singleton = new SafeSingleton();
                }
            }
        }
        return singleton;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
